package com.cyys.modules.interceptor;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.cyys.common.dataScope.DataScope;
import com.cyys.common.dataScope.DataScopeFuncEnum;
import com.cyys.modules.core.shiro.token.manage.TokenManager;
import com.cyys.modules.system.model.user.User;
import lombok.Setter;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.List;
import java.util.Map;

/**
 * 数据权限
 *
 * @author: Fred
 * @email 453086@qq.com
 * @create: 2021-05-25 11:12
 */
public class DataScopeInterceptor implements InnerInterceptor {

    @Setter
    private DataScopeHandle dataScopeHandle;

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
                            ResultHandler resultHandler, BoundSql boundSql) {
        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        String originalSql = boundSql.getSql();
        Object parameterObject = boundSql.getParameterObject();

        // 查找参数中包含DataScope类型的参数
        DataScope dataScope = findDataScopeObject(parameterObject);
        if (dataScope == null) {
            return;
        }
        User user = TokenManager.getToken();
        if (user != null) {
            // 如果是超级管理员，则不过滤数据
            if (!user.getId().equals("1") || dataScope.getFunc().getType().equals(DataScopeFuncEnum.COUNT.getType())) {
                if(user.getType().equals("5")){  //个人数据
                    originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = %s",
                            dataScope.getFunc().getType(), originalSql, dataScope.getSelfName(), user.getId());
                }else{
                    String scopeName = dataScope.getScopeName();
                    List<String> orgIds = dataScope.getOrgIds();

                    if (CollUtil.isEmpty(orgIds) && dataScopeHandle.calcScope(orgIds)) {
                        originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE 1 = 2",
                                dataScope.getFunc().getType(), originalSql);
                    } else {
                        String join = CollectionUtil.join(orgIds, ",");
                        originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s IN (%s)",
                                dataScope.getFunc().getType(), originalSql, scopeName, join);
                    }
                }
            }
        }
        mpBs.sql(originalSql);
    }

    /**
     * 查找参数是否包括DataScope对象
     *w
     * @param parameterObj 参数列表
     * @return DataScope
     */
    private DataScope findDataScopeObject(Object parameterObj) {
        if (parameterObj instanceof DataScope) {
            return (DataScope) parameterObj;
        } else if (parameterObj instanceof Map) {
            for (Object val : ((Map<?, ?>) parameterObj).values()) {
                if (val instanceof DataScope) {
                    return (DataScope) val;
                }
            }
        }
        return null;
    }

}